package implementation;
import GameData.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Scanner;

import protocol.Query;
import protocol.StateObject;

public class ExecUtils {
	private static int inputNumber = 1;
	private static int outputNumber = 1;
	private static String recordFileName = "output.wav";
	private static String outputFileDir = "/proj/speech/users/cs4706/jrb2137/partc/";
	private static FileWriter log = null;
	
	private static void exec(String command) {
		try {
			Process proc = Runtime.getRuntime().exec(command);
			InputStream stderr = proc.getErrorStream();
			InputStreamReader isr = new InputStreamReader(stderr);
			BufferedReader br = new BufferedReader(isr);
			String line = null;
			while ((line = br.readLine()) != null) {
				System.out.println(line);

			}
			int exitVal = proc.waitFor();
			if(exitVal != 0)
			    System.out.println("exited with error status: " + exitVal);
		} catch (Exception e) {
			System.out.println("Exec exception: " + e.getMessage());
		}
	}

	private static void exec_array(String[] commands) {
		try {
			Process proc = Runtime.getRuntime().exec(commands);
			InputStream stderr = proc.getErrorStream();
			InputStreamReader isr = new InputStreamReader(stderr);
			BufferedReader br = new BufferedReader(isr);
			String line = null;
			while ((line = br.readLine()) != null) {
				System.out.println(line);

			}
			int exitVal = proc.waitFor();
			if(exitVal != 0)
			    System.out.println("exited with error status: " + exitVal);
		} catch (Exception e) {
			System.out.println("Exec exception: " + e.getMessage());
		}
	}

	public static void getUserInput(Query query, String gram_name) {
		try{
			Date d = new Date(System.currentTimeMillis());
			log.write("\nTimestamp: "+d+"\n");
			query.setShortConf(null);
	
			/*System.out.println("begin speaking now...");
			String command = "/proj/speech/tools/autorecord/record.py 600";
			exec(command);
			System.out.println("input received");
	
			command = "/proj/speech/users/cs4706/asrhw/jrb2137/RecognizeConcepts.pl " + recordFileName + " " + gram_name;
			exec(command);*/
			
			String newFileName = "UserInput" + inputNumber++ + ".wav";
			//command = "mv -f " + recordFileName + " " + newFileName;
			//exec(command);
			log.write("User input captured in: "+newFileName + "\n");
			
			//TODO CHANGE THIS!
			///////////////////// FOR TESTING REMOTELY ONLY /////////////////////
			System.out.println("***reading from: UserInput" + inputNumber + ".wav");
			String command = "/proj/speech/users/cs4706/asrhw/jrb2137/RecognizeConcepts.pl " + newFileName + " " + gram_name;
			exec(command);
			
			//Don't forget to remove this in the method "getUserInputWithAwayTeam  (towards the bottom)" also!
			/////////////////////////////////////////////////////////////////////
			
			File f = new File("data.txt");
			Scanner s;
			try {
				s = new Scanner(f);
			} catch (FileNotFoundException e) {
				System.out.println("Unable to find the concepts.txt file: "+e.getMessage());
				return;
			}
			
			String c = "User Semantics:";
			String value = s.nextLine().trim();
			c += "\n\thome team: " + value;
			if( !value.equals("UNSPECIFIED") ){
				if(value.contains("diamond backs"))
					query.setHomeTeam("arizona diamondbacks");
				else
					query.setHomeTeam(value);
			}
			
			value = s.nextLine().trim();
			c += "\n\taway team: " + value;
			if( !value.equals("UNSPECIFIED") ){
				if(value.contains("diamond backs"))
					query.setAwayTeam("arizona diamondbacks");
				else
					query.setAwayTeam(value);
			}
			
			value = s.nextLine().trim();
			c += "\n\tdate:      " + value;
			if( !value.equals("UNSPECIFIED") ){
				if( value.contains("next"))
					query.setDate("next");
				else {
					String[] dateSplit = value.split(" ");
					String dayNumber = (dateSplit[1] + (dateSplit.length>2?(" "+dateSplit[2]):"")).trim();
					dayNumber = "" + Games.daySpellingToNumConverter.get(dayNumber);
					String date = dateSplit[0] + " " + dayNumber;
					query.setDate(date);
				}
			}
			
			value = s.nextLine().trim();
			c += "\n\tnum tix:   " + value;
			if( !value.equals("UNSPECIFIED") ){
				Scanner in = new Scanner(value);
				String numTix = "";
				while(in.hasNext()){
					String token = in.next();
					if(token.equals("one"))
						numTix += "1";
					else if(token.equals("two"))
						numTix += "2";
					else if(token.equals("three"))
						numTix += "3";
					else if(token.equals("four"))
						numTix += "4";
					else if(token.equals("five"))
						numTix += "5";
					else if(token.equals("six"))
						numTix += "6";
					else if(token.equals("seven"))
						numTix += "7";
					else if(token.equals("eight"))
						numTix += "8";
					else if(token.equals("nine"))
						numTix += "9";
					else if(token.equals("ten"))
						numTix += "10";
					else if(token.equals("eleven"))
						numTix += "11";
					else if(token.equals("twelve"))
						numTix += "13";
					else if(token.equals("thirteen"))
						numTix += "14";
					else if(token.equals("fourteen"))
						numTix += "14";
					else if(token.equals("fifteen"))
						numTix += "15";
					else if(token.equals("sixteen"))
						numTix += "16";
					else if(token.equals("seventeen"))
						numTix += "17";
					else if(token.equals("eighteen"))
						numTix += "18";
					else if(token.equals("nineteen"))
						numTix += "19";
					else if(token.equals("twenty")){
						if(in.hasNext())
							numTix += "2";
						else
							numTix += "20";
					}
					else if(token.equals("thirty")){
						if(in.hasNext())
							numTix += "3";
						else
							numTix += "30";
					}
					else if(token.equals("forty")){
						if(in.hasNext())
							numTix += "4";
						else
							numTix += "40";
					}
					else if(token.equals("fifty")){
						if(in.hasNext())
							numTix += "5";
						else
							numTix += "50";
					}
					else if(token.equals("sixty")){
						if(in.hasNext())
							numTix += "6";
						else
							numTix += "60";
					}
					else if(token.equals("seventy")){
						if(in.hasNext())
							numTix += "7";
						else
							numTix += "70";
					}
					else if(token.equals("eighty")){
						if(in.hasNext())
							numTix += "8";
						else
							numTix += "80";
					}
					else if(token.equals("ninety")){
						if(in.hasNext())
							numTix += "9";
						else
							numTix += "90";
					}
				}
				query.setNumTix(numTix);
			}
			
			value = s.nextLine().trim();
			c += "\n\tprice:     " + value;
			if( !value.equals("UNSPECIFIED") )
				query.setPrice(value);
			
			value = s.nextLine().trim();
			c += "\n\tdirective: " + value;
			if( !value.equals("UNSPECIFIED") )
				query.setShortConf(value);
			
			value = s.nextLine().trim();
			query.endTransaction();
			System.out.println("Ticket Info in Query: " + query.getTicketInfo());
			log.write("User input: "+value+"\n");
			log.write(c+"\n");
			log.flush();
		} catch(IOException e){
			System.out.println("error writing to the log");
		}
	}
	
	
	
	public static void playPrompt(String state, StateObject sdsState)
	{
		try{
			if(log == null)
					log = new FileWriter("dgw2109_jrb2137_jwg2116SDSlog" + System.currentTimeMillis());
			
			System.out.println("tts args: " + state);
			Date d = new Date(System.currentTimeMillis());
			log.write("\nTimestamp: "+d+"\n");
			log.write("State: "+sdsState.getState()+"\n");
			
			String fileName = "SystemOutput" + outputNumber++ + ".wav";
			String[] commands = new String[3];
			commands[0] = "/proj/speech/users/cs4706/jrb2137/tts.pl";   	
			commands[1] = state;
			commands[2] = fileName;
			exec_array(commands); 
			
			File f = new File("ttsoutput.txt");
			try {
				Scanner scan = new Scanner(f);
				log.write("System Prompt: "+scan.nextLine()+"\n");
			} catch (FileNotFoundException e) {
				System.out.println("file ttsoutput does not exist");
			}
				
			String command = "/proj/speech/tools/festival/speech_tools/bin/na_play " + outputFileDir + fileName;
			exec(command);
	
			//TODO comment / remove before submitting
//			try
//			{
//				Thread.sleep(5000);
//			}
//			catch(InterruptedException e)
//			{
//				System.out.println("didn't sleep");
//			}
	
			//////////////////////////////////////////////////////////////////
	
			command = "mv -f " + outputFileDir + fileName + " .";
			log.write("System output saved in: "+fileName+"\n");
			log.flush();
		}
		catch(IOException e){
			System.out.println("log file write error");
		}
	}

	public static boolean explicitConfirm(Query query, StateObject sdsState) {
		String state = "ExplicitConfirm" + query.getLastTransaction();
		playPrompt(state, sdsState);
		
		getUserInput(query, "gram_explicitconfirm");
		query.voidTransaction();
		if(query.getShortConf() != null && query.getShortConf().equals("yes"))
			return true;
		else
			return false;
	}

	public static void getUserInputWithAwayTeam(Query query, String gram_name) {
		try{
			Date d = new Date(System.currentTimeMillis());
			log.write("\nTimestamp: "+d+"\n");
			query.setShortConf(null);
	
			/*System.out.println("begin speaking now...");
			String command = "/proj/speech/tools/autorecord/record.py 600";
			exec(command);
			System.out.println("input received");
	
			command = "/proj/speech/users/cs4706/asrhw/jrb2137/RecognizeConcepts.pl " + recordFileName + " " + gram_name;
			exec(command);*/
			
			String newFileName = "UserInput" + inputNumber++ + ".wav";
			//command = "mv -f " + recordFileName + " " + newFileName;
			//exec(command);
			log.write("User input captured in: "+newFileName+"\n");
			
			
			//TODO CHANGE THIS TOO!
			///////////////////// FOR TESTING REMOTELY ONLY /////////////////////
			
			System.out.println("***reading from: UserInput" + inputNumber + ".wav");
			String command = "/proj/speech/users/cs4706/asrhw/jrb2137/RecognizeConcepts.pl " + newFileName + " " + gram_name;
			exec(command);
			System.out.println("***Just read the input");
			
			//Don't forget to remove this in the method "getUserInput (above)" also!
			/////////////////////////////////////////////////////////////////////
			
			
			
			File f = new File("data.txt");
			Scanner s;
			try {
				s = new Scanner(f);
			} catch (FileNotFoundException e) {
				System.out.println("Unable to find the concepts.txt file: "+e.getMessage());
				return;
			}
			
			
			String c = "User Semantics:\n\thome team: UNSPECIFIED";
			
			String value = s.nextLine().trim();
			String nextc = value;
			if( !value.equals("UNSPECIFIED") ){
				if(value.contains("diamond backs"))
					query.setAwayTeam("arizona diamondbacks");
				else
					query.setAwayTeam(value);
			}
			
			value = s.nextLine().trim();
			if( !nextc.equals("UNSPECIFIED") )
				c += "\n\taway team: " + nextc;
			else
				c += "\n\taway team: " + value;
			if( !value.equals("UNSPECIFIED") ){
				if(value.contains("diamond backs"))
					query.setAwayTeam("arizona diamondbacks");
				else
					query.setAwayTeam(value);
			}
			
			value = s.nextLine().trim();
			c += "\n\tdate:      " + value;
			if( !value.equals("UNSPECIFIED") )
				query.setDate(value);
			
			value = s.nextLine().trim();
			c += "\n\tnum tix:   " + value;
			if( !value.equals("UNSPECIFIED") ){
				Scanner in = new Scanner(value);
				String numTix = "";
				while(in.hasNext()){
					String token = in.next();
					if(token.equals("one"))
						numTix += "1";
					else if(token.equals("two"))
						numTix += "2";
					else if(token.equals("three"))
						numTix += "3";
					else if(token.equals("four"))
						numTix += "4";
					else if(token.equals("five"))
						numTix += "5";
					else if(token.equals("six"))
						numTix += "6";
					else if(token.equals("seven"))
						numTix += "7";
					else if(token.equals("eight"))
						numTix += "8";
					else if(token.equals("nine"))
						numTix += "9";
					else if(token.equals("ten"))
						numTix += "10";
					else if(token.equals("eleven"))
						numTix += "11";
					else if(token.equals("twelve"))
						numTix += "13";
					else if(token.equals("thirteen"))
						numTix += "14";
					else if(token.equals("fourteen"))
						numTix += "14";
					else if(token.equals("fifteen"))
						numTix += "15";
					else if(token.equals("sixteen"))
						numTix += "16";
					else if(token.equals("seventeen"))
						numTix += "17";
					else if(token.equals("eighteen"))
						numTix += "18";
					else if(token.equals("nineteen"))
						numTix += "19";
					else if(token.equals("twenty")){
						if(in.hasNext())
							numTix += "2";
						else
							numTix += "20";
					}
					else if(token.equals("thirty")){
						if(in.hasNext())
							numTix += "3";
						else
							numTix += "30";
					}
					else if(token.equals("forty")){
						if(in.hasNext())
							numTix += "4";
						else
							numTix += "40";
					}
					else if(token.equals("fifty")){
						if(in.hasNext())
							numTix += "5";
						else
							numTix += "50";
					}
					else if(token.equals("sixty")){
						if(in.hasNext())
							numTix += "6";
						else
							numTix += "60";
					}
					else if(token.equals("seventy")){
						if(in.hasNext())
							numTix += "7";
						else
							numTix += "70";
					}
					else if(token.equals("eighty")){
						if(in.hasNext())
							numTix += "8";
						else
							numTix += "80";
					}
					else if(token.equals("ninety")){
						if(in.hasNext())
							numTix += "9";
						else
							numTix += "90";
					}
				}
				query.setNumTix(numTix);
			}
			
			value = s.nextLine().trim();
			c += "\n\tprice:     " + value;
			if( !value.equals("UNSPECIFIED") )
				query.setPrice(value);
			
			value = s.nextLine().trim();
			c += "\n\tdirective: " + value;
			if( !value.equals("UNSPECIFIED") )
				query.setShortConf(value);
			
			value = s.nextLine().trim();
			query.endTransaction();
			
			System.out.println("Ticket Info in Query: " + query.getTicketInfo());
			log.write("User input: "+value+"\n");
			log.write(c + "\n");
			log.flush();
		}catch(IOException e){
			System.out.println("error writing to the log file");
		}
	}
}
